import axios from 'axios'
import { ElNotification, ElMessageBox } from 'element-plus'
import sysConfig from "@/config"
import tool from '@/utils/tool'
import router from '@/router'
import store from '@/store'
axios.defaults.baseURL = ''



axios.defaults.timeout = sysConfig.TIMEOUT

let tokenUpdateing = false,//token是否处于更新中
	reqLists = []//更新token时请求的队列 

// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.cookie.get("TOKEN")
		let refreshToken = tool.data.get("REFRESHTOKEN")
		let roleList = tool.data.get("ROLELIST")
		let departmentIds = tool.data.get("DEPARTMENTID")
		if (token) {
			config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
			config.headers.rolrList = roleList
			config.headers.departmentIds = departmentIds
			config.headers.refreshToken = refreshToken
		}
		// if (!sysConfig.REQUEST_CACHE && config.method == 'get') {
		// 	config.params = config.params || {}
		// 	config.params['_'] = new Date().getTime()
		// }
		Object.assign(config.headers, sysConfig.HEADERS)
		return config
	},
	(error) => {
		return Promise.reject(error)
	}
)

// FIX 多个API同时401时疯狂弹窗BUG
let MessageBox_403_show = false

// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {
		return response
	},
	async (error) => {
		if (error.response) {
			if (error.response.status == 401) {
				if (!MessageBox_403_show) {
					MessageBox_403_show = true
					ElMessageBox.confirm(error.response.data.message, {
						type: 'error',
						closeOnClickModal: false,
						center: true,
						confirmButtonText: '重新登录',
						beforeClose: (action, instance, done) => {
							MessageBox_403_show = false
							done()
						}
					}).then(() => {
						router.replace({ path: '/login' })
					}).catch(() => { })
				}
			} else if (error.response.status == 403) {
				if (!tokenUpdateing) {
					tokenUpdateing = true //关闭token更新 
					await store.dispatch("login/getRefreshToken")
					// let token = error.response.headers.authorization
					// console.log(1)
					// 获取刷新之后的token数据
					// tool.cookie.set('TOKEN', token)
					// error.config.headers.Authorization = sysConfig.TOKEN_PREFIX + token

					//token更新完成 ——> 重新发起请求
					reqLists.forEach((cb) => cb(tool.cookie.get("TOKEN")))
					reqLists = []//清空请求队列

					// 重新发起请求
					tokenUpdateing = false
					return await axios(error.config)
				} else {
					// Promise用函数形式将 resolve 存入，等待刷新后再执行
					return new Promise((resolve) => {
						reqLists.push(token => {
							error.config.headers.Authorization = sysConfig.TOKEN_PREFIX + tool.cookie.get("TOKEN")
							resolve(axios(error.config))
						})
					})
				}
			} else if (error.response.status === 402) {
				if (!MessageBox_403_show) {
					MessageBox_403_show = true
					ElMessageBox.confirm(error.response.data.message, {
						type: 'error',
						closeOnClickModal: false,
						center: true,
						confirmButtonText: '重新登录',
						beforeClose: (action, instance, done) => {
							MessageBox_403_show = false
							done()
						}
					}).then(() => {
						router.replace({ path: '/login' })
					}).catch(() => { })
				}
			} else if (error.response.status !== 200) {
				if (!error.response.data.message) {
					error.response.data = {
						code: error.response.status,
						message: error.response.statusText
					}
				}
				ElNotification.error({
					title: '错误信息',
					message: error.response.data.message ? error.response.data.message : error.response.statusText
				})
			}
		} else {
			if (error.response) {
				console.log(error)
				ElNotification.error({
					title: '请求错误',
					message: "请求服务器无响应！"
				})
				error.response.data = {
					message: '请求服务器无响应',
					code: 502
				}
			} else {
				ElNotification.error({
					title: '请求错误',
					message: "请求超时"
				})
				error = {
					'response': {
						'data': {
							'code': 502,
							'message': '请求超时'
						}
					}
				}
			}

		}
		return Promise.reject(error.response)
	}
)

var http = {

	/** get 请求
	 * @param  {string} url 接口地址
	 * @param  {object} params 请求参数
	 * @param  {object} config 参数
	 */
	get: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get',
				url: url,
				params: params,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},

	/** post 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},
	postParam: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				params: data,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},
	/** put 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	put: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},

	/** patch 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	patch: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},

	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	delete: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				// data: data,
				params: data,
				...config
			}).then((response) => {
				resolve(response.data)
			}).catch((error) => {
				reject(error)
			})
		})
	},

	/** jsonp 请求
	 * @param  {string} url 接口地址
	 * @param  {string} name JSONP回调函数名称
	 */
	jsonp: function (url, name = 'jsonp') {
		return new Promise((resolve) => {
			var script = document.createElement('script')
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] = (response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name]
				} catch (e) {
					window[name] = undefined
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}

export default http
